package com.springboot;

import org.apache.catalina.LifecycleException;
import org.apache.catalina.Server;
import org.apache.catalina.Service;
import org.apache.catalina.connector.Connector;
import org.apache.catalina.core.StandardContext;
import org.apache.catalina.core.StandardEngine;
import org.apache.catalina.core.StandardHost;
import org.apache.catalina.startup.Tomcat;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;
import org.springframework.web.servlet.DispatcherServlet;

import java.util.Map;

public class LuoSpringApplication {
    public static void run(Class clazz){
        //使用注解作为配置类创建spring容器
        AnnotationConfigWebApplicationContext applicationContext = new AnnotationConfigWebApplicationContext();
        applicationContext.register(clazz);//将客户端传递来的类作为配置类
        applicationContext.refresh();
        //startTomcat(applicationContext);
        WebServer webServer=getWebServer(applicationContext);//将spring容器对象传递过去
        webServer.start(applicationContext);
    }

    private static WebServer getWebServer(WebApplicationContext applicationContext) {
        //判断客户端的pom文件中的容器是那个，并根据pom文件生成对应的容器，并启动

        //这里判断用了一个思想：因为WebServer有两个实现类，这tomcat和jetty两个容器类都是只是
        // 在springboot中定义了的，那么只需要我们客户端那边将需要的bean给注入到spring的context容器中
        //再判断context容器中是否有且仅有一个容器，那么就返回这个容器的对象
        Map<String, WebServer> webServer = applicationContext.getBeansOfType(WebServer.class);
        if (webServer.isEmpty()){
            //说明客户端并没有定义容器，无法启动
            throw new NullPointerException("没有找到容器");
        }
        if (webServer.size()>1){
            //用户客户端定义了多个容器，无法启动
            throw new IllegalStateException("定义多个容器错误");
        }
        return webServer.values().stream().findFirst().get();
    }

    private static void startTomcat(WebApplicationContext applicationContext) {
        Tomcat tomcat = new Tomcat();
        Server server = tomcat.getServer();
        Service service = server.findService("Tomcat");
        Connector connector = new Connector();
        connector.setPort(8080);
        StandardEngine standardEngine = new StandardEngine();
        standardEngine.setDefaultHost("localhost");
        StandardHost standardHost = new StandardHost();
        standardHost.setName("localhost");
        String contextPath="";
        StandardContext standardContext = new StandardContext();
        standardContext.setPath(contextPath);
        standardContext.addLifecycleListener(new Tomcat.FixContextListener());
        standardHost.addChild(standardContext);
        standardEngine.addChild(standardHost);
        service.setContainer(standardEngine);
        service.addConnector(connector);
        tomcat.addServlet(contextPath,"dispatcher",new DispatcherServlet(applicationContext));
        standardContext.addServletMappingDecoded("/","dispatcher");
        try {
            tomcat.start();
        } catch (LifecycleException e) {


        }
    }
}
